package com.yykj.tencent.im.server.service.impl;

import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.util.PageRequestUtil;
import com.yykj.common.vo.PageData;
import com.yykj.tencent.im.server.converter.C2CMessageConverter;
import com.yykj.tencent.im.server.dto.C2CMessageDTO;
import com.yykj.tencent.im.server.form.C2CMessageForm;
import com.yykj.tencent.im.server.form.C2CPageForm;
import com.yykj.tencent.im.server.model.entity.C2CMessage;
import com.yykj.tencent.im.server.model.entity.Friend;
import com.yykj.tencent.im.server.model.repository.C2CMessageRepository;
import com.yykj.tencent.im.server.model.repository.FriendRepository;
import com.yykj.tencent.im.server.service.C2CMessageService;
import com.yykj.tencent.im.server.utils.Map2Object;
import com.yykj.tencent.im.server.utils.TimestampUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class C2CMessageServiceImpl implements C2CMessageService {

    @Value("${environment}")
    private String environment;

    private C2CMessageRepository c2CMessageRepository;
    private FriendRepository friendRepository;
    @Autowired
    public void setC2CMessageRepository(C2CMessageRepository c2CMessageRepository){
        this.c2CMessageRepository = c2CMessageRepository;
    }
    @Autowired
    public void setFriendRepository(FriendRepository friendRepository){
        this.friendRepository = friendRepository;
    }


    private static final String IMPORT_MSG_COMMAND = "importmsg";
    private static final String BATCH_SEND_MSG_COMMAND = "batchsendmsg";
    private static final String ADMIN_GET_ROAM_MSG_COMMAND = "admin_getroammsg";
    private static final String ADMIN_MSG_WITHDRAW_COMMAND = "admin_msgwithdraw";
    private static final String ADMIN_SET_MSG_READ_COMMAND = "admin_set_msg_read";
    private static final String GET_C2C_UNREAD_MSG_NUM_COMMAND = "get_c2c_unread_msg_num";
    /**
     * 请求接口
     */
    private final String api_url = "%s/%s/%s";


    @Override
    @Async
    public void addC2CMessage(Map<String,Object> map) {
        // map->C2CMessageForm
        C2CMessageForm msg = (C2CMessageForm) Map2Object.mapToObject(map,C2CMessageForm.class);
        // C2CMessageForm --> C2CMessage
        C2CMessage c2CMessage = new C2CMessage();
        BeanUtils.copyProperties(msg,c2CMessage);
        c2CMessage.setMsgTime(TimestampUtil.ofEpochSecond(msg.getMsgTime()));
        c2CMessage.setEnvironment(environment);
        c2CMessageRepository.save(c2CMessage);
        //更新好友交互
        Friend friend = friendRepository.findByFromAccountAndToAccount(msg.getFromAccount(),msg.getToAccount());
        if(friend == null){
            friend = new Friend();
            friend.setEnvironment(environment);
            friend.setFromAccount(msg.getFromAccount());
            friend.setToAccount(msg.getToAccount());
            friend.setNumber(1);
            friend.setType("F");
            friend.setUpdateTime(LocalDateTime.now());
        }else{
            friend.setUpdateTime(LocalDateTime.now());
            friend.setNumber(friend.getNumber()+1);
        }
        friendRepository.save(friend);
    }

    @Override
    public PageData<C2CMessageDTO> listC2CMessages(C2CPageForm form) {
        form.setEnv(environment);
        if (form.getFromAccount() == null ) {
            throw new NormalException(ResultEnums.PARAM_ERROR);
        }
        Pageable page = PageRequest.of(PageRequestUtil.getPage(form.getCurrentPage())
                ,PageRequestUtil.getSize(form.getPageSize())
                , Sort.by(Sort.Direction.DESC, "msgTime"));
        Page<C2CMessage> list = c2CMessageRepository.findAll(new Specification<C2CMessage>(){
            @Override
            public Predicate toPredicate(Root<C2CMessage> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
                List<Predicate> predicateList = new ArrayList<>();
                predicateList.add(builder.equal(root.get("fromAccount"),form.getFromAccount()));
                predicateList.add(builder.equal(root.get("toAccount"),form.getToAccount()));
                predicateList.add(builder.equal(root.get("environment"),form.getEnv()));
                Predicate[] predicates = new Predicate[predicateList.size()];
                return query.where(predicateList.toArray(predicates)).getRestriction();
            }
        },page);

        PageData<C2CMessageDTO> result = new PageData<C2CMessageDTO>();
        PageData<C2CMessage> pageData = PageData.formatList(list, form.getCurrentPage(), form.getPageSize());
        BeanUtils.copyProperties(pageData,result);
        result.setList(C2CMessageConverter.convert(list.getContent()));
        return result;
    }


}
